package com.itmk.web.sys_user.controller;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.code.kaptcha.impl.DefaultKaptcha;
import com.itmk.jwt.JwtUtils;
import com.itmk.utils.ResultUtils;
import com.itmk.utils.ResultVo;
import com.itmk.web.department.entity.Department;
import com.itmk.web.department.entity.SelectDept;
import com.itmk.web.sys_menu.entity.AssignTreeParm;
import com.itmk.web.sys_menu.entity.AssignTreeVo;
import com.itmk.web.sys_menu.entity.SysMenu;
import com.itmk.web.sys_menu.service.SysMenuService;
import com.itmk.web.sys_user.entity.*;
import com.itmk.web.sys_user.service.SysUserService;
import com.itmk.web.sys_user_role.entity.SysUserRole;
import com.itmk.web.sys_user_role.service.SysUserRoleService;
import org.apache.commons.lang.StringUtils;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
import org.springframework.web.bind.annotation.*;
import sun.misc.BASE64Encoder;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;



@RequestMapping("/api/sysUser")
@RestController
public class SysUserController {
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private SysUserRoleService sysUserRoleService;
    @Autowired
    private DefaultKaptcha defaultKaptcha;
    @Autowired
    private JwtUtils jwtUtils;
    @Autowired
    private SysMenuService sysMenuService;
    @Autowired
    private AuthenticationManager authenticationManager;
    @Autowired
    private PasswordEncoder passwordEncoder;


    //新增
    @PreAuthorize("hasAuthority('sys:user:add')")
    @PostMapping
    public ResultVo add(@RequestBody SysUser sysUser){
        sysUser.setCreateTime(new Date());
        sysUser.setIsAdmin("1");
        sysUser.setPassword(passwordEncoder.encode(sysUser.getPassword()));
        sysUserService.saveUser(sysUser);
        return ResultUtils.success("新增成功");
    }

    //编辑
    @PreAuthorize("hasAuthority('sys:user:edit')")
    @PutMapping
    public ResultVo edit(@RequestBody SysUser sysUser){
        sysUser.setUpdateTime(new Date());
        sysUserService.editUser(sysUser);
        return ResultUtils.success("编辑成功");


    }

    //删除
    @PreAuthorize("hasAuthority('sys:user:delete')")
    @DeleteMapping("/{userId}")
    public ResultVo delete(@PathVariable("userId") Long userId ){
        sysUserService.deleteUser(userId);
            return ResultUtils.success("删除成功");


    }

    //列表
    @GetMapping("/list")
    //列表
    public ResultVo list(SysUserPage parm){
//        //构造分页对象
//        IPage<SysUser> page = new Page<>(parm.getCurrentPage(),parm.getPageSize());
//        //构造查询条件
//        MPJLambdaWrapper<SysUser> query = new MPJLambdaWrapper<>();
//        query.selectAll(SysUser.class)
//                .select(Department::getDeptName)
//                .leftJoin(Department.class,Department::setDeptId,SysUser::getDeptId)
//                .eq(SysUser::getIsAdmin,"0");
//        if(StringUtils.isNotEmpty(parm.getNickName())){
//            query.like(SysUser::getNickName,parm.getNickName());
//        }
//        if(StringUtils.isNotEmpty(parm.getPhone())){
//            query.like(SysUser::getPhone,parm.getPhone());
//        }
//        //排序，新的新出
//        query.orderByDesc(SysUser::getCreateTime);
//        IPage<SysUser> list =sysUserService.page(page,query);
//        return ResultUtils.success("查询成功",list);
     IPage<SysUser> list = sysUserService.getList(parm);
     return ResultUtils.success("查询成功",list);
    }
    //根据用户id查询角色
    @GetMapping("/getRoleList")
    public ResultVo getRoleList(Long userId){
        QueryWrapper<SysUserRole> query = new QueryWrapper<>();
        query.lambda().eq(SysUserRole::getUserId,userId);
        List<SysUserRole> list = sysUserRoleService.list(query);
        //角色id
        List<Long> roleList = new ArrayList<>();
        Optional.ofNullable(list).orElse(new ArrayList<>())
                .forEach(item ->{
                    roleList.add(item.getRoleId());
                });
        return ResultUtils.success("查询成功",roleList);
    }

    //重置密码
    @PreAuthorize("hasAuthority('sys:user:reset')")
    @PostMapping("/resetPassword")
    public  ResultVo resetPassword(@RequestBody SysUser sysUser){
        UpdateWrapper<SysUser> query = new UpdateWrapper();
        query.lambda().eq(SysUser::getUserId,sysUser.getUserId())
                .set(SysUser::getPassword,passwordEncoder.encode("123456"));
        if(sysUserService.update(query)){
            return ResultUtils.success("密码重置成功");
        }
        return ResultUtils.success("密码重置失败");
    }

    //图片验证码
    @PostMapping("/getImage")
    public ResultVo imageCode(HttpServletRequest request){
        // 生成验证码
        String text = defaultKaptcha.createText();
        // 验证码存到session
        HttpSession session = request.getSession();
        session.setAttribute("code", text);
        // 生成图片，转换为base64
        BufferedImage bufferedImage = defaultKaptcha.createImage(text);
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        try {
            ImageIO.write(bufferedImage, "jpg", outputStream);
            BASE64Encoder encoder = new BASE64Encoder();
            String base64 = encoder.encode(outputStream.toByteArray());
            String captchaBase64 = "data:image/jpeg;base64," + base64.replaceAll("\r\n", "");
            return ResultUtils.success("生成成功", captchaBase64);
        } catch (IOException e) {
            e.printStackTrace();
            return ResultUtils.error("生成验证码失败");
        } finally {
            try {
                outputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }


    }

    // 登录
    @PostMapping("/login")
    public ResultVo login(@RequestBody LoginParm parm, HttpServletRequest request) {
        // 获取session里面的code验证码
        HttpSession session = request.getSession();
        String code = (String) session.getAttribute("code");
        // 获取前端传递过来的验证码
        String codeParm = parm.getCode();
        if (StringUtils.isEmpty(code)) {
            // 生成新的验证码
//            String newCaptcha = generateNewCaptcha(request);
//            return ResultUtils.error("验证码过期!", newCaptcha);
            return ResultUtils.error("验证码过期!");

        }
        // 对比验证码
        if (!codeParm.equals(code)) {
            // 生成新的验证码
//            String newCaptcha = generateNewCaptcha(request);
//            return ResultUtils.error("验证码错误!", newCaptcha);
           return ResultUtils.error("验证码错误!");
        }
        String password = passwordEncoder.encode(parm.getPassword());
        // 验证用户信息,让springsecurity来做
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(parm.getUsername(),parm.getPassword());
        Authentication authenticate = authenticationManager.authenticate(authenticationToken);
        SecurityContextHolder.getContext().setAuthentication(authenticate);
        SysUser user = (SysUser)authenticate.getPrincipal();
//        String rawPassword = "11";
//        String encryptedPassword = passwordEncoder.encode(rawPassword);
//        System.out.println(encryptedPassword);
//        QueryWrapper<SysUser> query = new QueryWrapper<>();
//        query.lambda().eq(SysUser::getUsername, parm.getUsername())
//                .eq(SysUser::getPassword, DigestUtils.md5DigestAsHex(parm.getPassword().getBytes()));//这里密码被加密了，上面不多个加密是登录不上的
//        QueryWrapper<SysUser> query = new QueryWrapper<>();
//        query.lambda().eq(SysUser::getUsername, parm.getUsername())
//                .eq(SysUser::getPassword, parm.getPassword()); // 直接使用明文密码比较
//        SysUser user = sysUserService.getOne(query);
//        if (user == null) {
//            return ResultUtils.error("用户名或密码错误!");
//        }
//        if ("1".equals(user.getStatus())) {
//            return ResultUtils.error("账户被停用，请联系管理员!");
//        }
        // 返回登录信息
        LoginVo vo = new LoginVo();
        vo.setUserId(user.getUserId());
        vo.setNickName(user.getNickName());
        vo.setImage(user.getImage());
        if(StringUtils.isNotEmpty(user.getIsAdmin())&& user.getIsAdmin().equals("1")){
            vo.setType("1");
        }else {
            vo.setType("0");
        }
        //生成token
        Map<String,String> map = new HashMap<>();
        map.put("userId",Long.toString(user.getUserId()));
        map.put("username",user.getUsername());
        String token = jwtUtils.generateToken(map);
        vo.setToken(token);
        return ResultUtils.success("登录成功", vo);
    }
    // 新增的生成验证码方法（复用原有逻辑）
    private String generateNewCaptcha(HttpServletRequest request) {
        try {
            String text = defaultKaptcha.createText();
            request.getSession().setAttribute("code", text);

            BufferedImage bufferedImage = defaultKaptcha.createImage(text);
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            ImageIO.write(bufferedImage, "jpg", outputStream);
            BASE64Encoder encoder = new BASE64Encoder();
            String base64 = encoder.encode(outputStream.toByteArray());
            return "data:image/jpeg;base64," + base64.replaceAll("\r\n", "");
        } catch (IOException e) {
            e.printStackTrace();
            return null; // 如果生成失败返回null，前端需要处理这种情况
        }
    }
    //查询菜单树
    @GetMapping("/getAssignTree")
    public ResultVo getAssignTree(AssignTreeParm parm){
        AssignTreeVo assignTree = sysUserService.getAssignTree(parm);
        return ResultUtils.success("查询成功",assignTree);
    }

    //重置密码
    @PostMapping("/updatePassword")
    public ResultVo updatePassword(@RequestBody UpdatePassword parm){
        SysUser user = sysUserService.getById((parm.getUserId()));
//        if(!parm.getOldPassword().equals(user.getPassword())){
//            return ResultUtils.error("原密码不正确");
//        }
        if(!passwordEncoder.matches(parm.getOldPassword(),user.getPassword())){
            return ResultUtils.error("原密码不正确");
        }
        //更新条件
        UpdateWrapper<SysUser> query = new UpdateWrapper<>();
        query.lambda().set(SysUser::getPassword,passwordEncoder.encode(parm.getPassword()))
                .eq(SysUser::getUserId,parm.getUserId());
        if(sysUserService.update(query)){
            return ResultUtils.success("密码修改成功");
        }
        return ResultUtils.error("密码修改失败");
    }

    //获取用户信息
    @GetMapping("/getInfo")
    public  ResultVo getInfo(Long userId){
        //根据id查询用户信息
         SysUser user = sysUserService.getById(userId);
         List<SysMenu> menuList = null;
         //判断是不是超级管理员
         if(StringUtils.isNotEmpty(user.getIsAdmin())&&"1".equals(user.getIsAdmin())){
             menuList = sysMenuService.list();
         }else {
             menuList = sysMenuService.getMenuByUserId(user.getUserId());
         }
         List<String> collet = Optional.ofNullable(menuList).orElse(new ArrayList<>())
                 .stream()
                 .filter(item -> item != null && StringUtils.isNotEmpty(item.getCode()))
                 .map(item -> item.getCode())
                 .collect(Collectors.toList());
         String[] strings = collet.toArray(new String[collet.size()]);
         UserInfo userInfo = new UserInfo();
         userInfo.setName(user.getNickName());
         userInfo.setUserId(user.getUserId());
         userInfo.setPermissons(collet.toArray());
         return ResultUtils.success("查询成功",userInfo);

    }
    //退出登录
    @PostMapping("/loginOut")
    public ResultVo loginOut(HttpServletRequest request, HttpServletResponse response){
        Authentication authentication =SecurityContextHolder.getContext().getAuthentication();
        if (authentication != null){
            new SecurityContextLogoutHandler().logout(request,response,authentication);
        }
        return ResultUtils.success("退出成功");
    }
    //启用停用
    @PreAuthorize("hasAuthority('sys:user:enabled')")
    @PostMapping("/enabledUser")
    public ResultVo enabledUser(@RequestBody Map<String, Object> params){
        // 更健壮的空值检查
        if (params == null || !params.containsKey("userId") || !params.containsKey("enabled")) {
            return ResultUtils.error("请求参数不完整");
        }

        try {
            Long userId = Long.valueOf(params.get("userId").toString());
            boolean enabled = Boolean.parseBoolean(params.get("enabled").toString());

            // 创建只含必要字段的更新对象
            SysUser updateUser = new SysUser();
            updateUser.setUserId(userId);
            updateUser.setEnabled(enabled);

            // 检查service是否注入成功
            if (sysUserService == null) {
                return ResultUtils.error("系统服务异常");
            }

            boolean success = sysUserService.updateById(updateUser);
            return success ? ResultUtils.success("操作成功") : ResultUtils.error("操作失败");
        } catch (Exception e) {

            return ResultUtils.error("操作失败: " + e.getMessage());
        }
    }


    @GetMapping("/getSelectUser")
    public ResultVo getSelectUser(Long deptId){
        QueryWrapper<SysUser> query = new QueryWrapper<>();
        query.lambda().eq(SysUser::getDeptId,deptId).orderByDesc(SysUser::getUsername);
        List<SysUser> list = sysUserService.list(query);
        List<SelectDept> deptList = new ArrayList<>();
        if(list.size()>0){
            for(int i=0;i<list.size();i++){
                SelectDept dept = new SelectDept();
                dept.setLabel(list.get(i).getNickName());
                dept.setValue(Integer.parseInt(list.get(i).getUserId().toString()));
                deptList.add(dept);
            }
        }
        return ResultUtils.success("查询成功",deptList);
    }
    @Test
    public void testPassword() {
        String rawPassword = "11";
        String encryptedPassword = passwordEncoder.encode(rawPassword);

        System.out.println("加密后的密码: " + encryptedPassword);
        System.out.println("验证结果: " + passwordEncoder.matches(rawPassword, encryptedPassword));}
}
